#ifndef USB_TYPEDEF_H
#define USB_TYPEDEF_H

#include "attribute_typedef.h"
#include "remote_control.h"
#include "struct_typedef.h"

#define DEBUG_PACKAGE_NUM 10

#define DATA_DOMAIN_OFFSET 0x08

// clang-format off
#define SEND_SOF    ((uint8_t)0x99)
#define RECEIVE_SOF ((uint32_t)0x23)

// #define DEBUG_DATA_SEND_ID        ((uint8_t)0x01)
// #define IMU_DATA_SEND_ID          ((uint8_t)0x02)
#define ROBOT_INFO_DATA_SEND_ID   ((uint8_t)0x5D)
// #define PID_DEBUG_DATA_SEND_ID    ((uint8_t)0x04)
#define ALL_ROBOT_HP_SEND_ID      ((uint8_t)0x5B)
#define GAME_STATUS_SEND_ID       ((uint8_t)0x5C)
// #define ROBOT_MOTION_DATA_SEND_ID ((uint8_t)0x07)
#define VISION_SEND_ID            ((uint8_t)0x5A)

#define ROBOT_CMD_DATA_RECEIVE_ID  ((uint8_t)0xA3)
// #define PID_DEBUG_DATA_RECEIVE_ID  ((uint8_t)0x02)
// #define VIRTUAL_RC_DATA_RECEIVE_ID ((uint8_t)0x03)
#define VISION_RECEIVE_ID          ((uint8_t)0xA5)
#define SIMULATION_RECEIVE_ID      ((uint8_t)0xA4)

// #define ROBOT_INFO_DATA_SEND_LEN   ((int)7)
// #define ALL_ROBOT_HP_SEND_LEN      ((int)32)
// #define GAME_STATUS_SEND_LEN       ((int)3)
// #define VISION_SEND_LEN            ((int)27)

// #define ROBOT_CMD_DATA_RECEIVE_LEN  ((int)5)
// #define VISION_RECEIVE_LEN          ((int)48)
// #define SIMULATION_RECEIVE_LEN      ((int)24)

// clang-format on

typedef struct
{
    uint8_t sof;  // 数据帧起始字节，固定值为 0x5A
    uint8_t len;  // 数据段长度
    uint8_t id;   // 数据段id
    uint8_t crc;  // 数据帧头的 CRC8 校验
} __packed__ FrameHeader_t;
/*-------------------- Send --------------------*/

// // 串口调试数据包
// typedef struct
// {
//     // FrameHeader_t frame_header;  // 数据段id = 0x01
//     // uint32_t time_stamp;
//     uint8_t header;
//     uint8_t id;
//     struct
//     {
//         uint8_t name[10];
//         uint8_t type;
//         float data;
//     } __packed__ packages[DEBUG_PACKAGE_NUM];
//     uint16_t checksum;
// } __packed__ SendDataDebug_s;

// // IMU 数据包
// typedef struct
// {
//     // FrameHeader_t frame_header;  // 数据段id = 0x02
//     // uint32_t time_stamp;
//     uint8_t header;
//     uint8_t id;
//     struct
//     {
//         float yaw;    // rad
//         float pitch;  // rad
//         float roll;   // rad

//         float yaw_vel;    // rad/s
//         float pitch_vel;  // rad/s
//         float roll_vel;   // rad/s

//         // float x_accel;  // m/s^2
//         // float y_accel;  // m/s^2
//         // float z_accel;  // m/s^2
//     } __packed__ data;
//     uint16_t crc;
// } __packed__ SendDataImu_s;

// 机器人信息数据包
typedef struct
{
    uint8_t id;             // 数据段id = 0x5D
    struct
    {
        uint8_t robot_id;       
        uint16_t current_hp;
        uint16_t shooter_heat;
        bool team_color;
        bool is_attacked;


    } __packed__ data;
    uint16_t crc;
} __packed__ SendDataRobotInfo_s;

// // PID调参数据包
// typedef struct
// {
//     FrameHeader_t frame_header;  // 数据段id = 0x04
//     uint32_t time_stamp;
//     struct
//     {
//         float fdb;
//         float ref;
//         float pid_out;
//     } __packed__ data;
//     uint16_t crc;
// } __packed__ SendDataPidDebug_s;

// 全场机器人hp信息数据包
typedef struct
{
    // FrameHeader_t frame_header;  // 数据段id = 0x05
    // uint32_t time_stamp;
    // uint8_t header;
    uint8_t id;             // 数据段id = 0x5B
    struct
    {
        uint16_t red_1_robot_hp;
        uint16_t red_2_robot_hp;
        uint16_t red_3_robot_hp;
        uint16_t red_4_robot_hp;
        uint16_t red_5_robot_hp;
        uint16_t red_7_robot_hp;
        uint16_t red_outpost_hp;
        uint16_t red_base_hp;
        uint16_t blue_1_robot_hp;
        uint16_t blue_2_robot_hp;
        uint16_t blue_3_robot_hp;
        uint16_t blue_4_robot_hp;
        uint16_t blue_5_robot_hp;
        uint16_t blue_7_robot_hp;
        uint16_t blue_outpost_hp;
        uint16_t blue_base_hp;
    } __packed__ data;
    uint16_t crc;
} __packed__ SendDataAllRobotHp_s;

// 比赛信息数据包
typedef struct
{
    // FrameHeader_t frame_header;  // 数据段id = 0x06
    // uint32_t time_stamp;
    // uint8_t header;
    uint8_t id;             // 数据段id = 0x5C
    struct
    {
        uint8_t game_progress;
        uint16_t stage_remain_time;
        bool is_canter_buff_down;
        uint8_t center_buff_owner;
    } __packed__ data;
    uint16_t crc;
} __packed__ SendDataGameStatus_s;

// // 机器人运动数据包
// typedef struct
// {
//     FrameHeader_t frame_header;  // 数据段id = 0x07
//     uint32_t time_stamp;
//     struct
//     {
//         struct
//         {
//             float vx;
//             float vy;
//             float wz;
//         } __packed__ speed_vector;
//     } __packed__ data;
//     uint16_t crc;
// } __packed__ SendDataRobotMotion_s;

// 视觉发送数据包
typedef struct
{
    // FrameHeader_t frame_header;  // 数据段id = 0x08
    // uint32_t time_stamp;
    // uint8_t header;
    uint8_t id;                // 数据段id = 0x5A
    uint32_t time_stamp;
    struct
    {
        uint8_t detect_color : 1;      // 0-red 1-blue 2-unknown
        bool reset_tracker: 1;  // 0-不重新跟踪 1-重新跟踪
        uint8_t reserved : 6;
                
        float roll;   // rad
        float pitch;  // rad
        float yaw;    // rad
        float aim_x;
        float aim_y;
        float aim_z;
    } __packed__ data;
    uint16_t crc;
} __packed__ SendDataVision_s;
// typedef struct
// {
//     uint8_t header = 0x5A;
//     uint8_t detect_color : 1; // 0-red 1-blue 2-unknown
//     bool reset_tracker : 1;   // 0-不重新跟踪 1-重新跟踪
//     uint8_t reserved : 6;

//     float roll;  // rad
//     float pitch; // rad
//     float yaw;   // rad
//     float aim_x;
//     float aim_y;
//     float aim_z;
//     uint16_t crc;

// } __packed__ SendDataVision_s;

/*-------------------- Receive --------------------*/
typedef struct RobotCmdData
{
    FrameHeader_t frame_header;  // 数据段id = 0x01
    uint32_t time_stamp;
    // uint8_t header;
    // uint8_t id;                // 数据段id = 0xA3
    struct
    {
        bool stop_gimbal_scan;  // 云台是否扫描 1-不扫描 0-扫描
        float chassis_spin_vel; //底盘小陀螺速度， 单位rad/s
        float speed_k;


    } __packed__ data;
    uint16_t checksum;
} __packed__ ReceiveDataRobotCmd_s;

// // PID调参数据包
// typedef struct
// {
//     FrameHeader_t frame_header;  // 数据段id = 0x02
//     uint32_t time_stamp;
//     struct
//     {
//         float kp;
//         float ki;
//         float kd;
//         float max_out;
//         float max_iout;
//     } __packed__ data;
//     uint16_t crc;
// } __packed__ ReceiveDataPidDebug_s;

// // 虚拟遥控器数据包
// typedef struct
// {
//     FrameHeader_t frame_header;  // 数据段id = 0x03
//     uint32_t time_stamp;
//     RC_ctrl_t data;
//     uint16_t crc;
// } __packed__ ReceiveDataVirtualRc_s;

// 视觉接收数据包
typedef struct
{
    FrameHeader_t frame_header; // 数据段id = 0x04
    uint32_t time_stamp;
    // uint8_t header;
    // uint8_t id;                 // 数据段id = 0xA5
    struct
    {
        bool tracking;          // 代表当前是否锁定目标
        uint8_t robot_id : 3;         // 0-outpost 6-guard 7-base
        uint8_t armors_num : 3; // 2-balance 3-outpost 4-normal
        uint8_t reserved : 1;

        float x;                // 目标在世界坐标系下的 x 坐标
        float y;                // 目标在世界坐标系下的 Y 坐标
        float z;                // 目标在世界坐标系下的 Z 坐标

        float yaw;              // 目标在世界坐标系下的倾斜角度
        
        float vx;               // 目标在世界坐标系下 x 方向的速度
        float vy;               // 目标在世界坐标系下 y 方向的速度
        float vz;               // 目标在世界坐标系下 z 方向的速度

        float v_yaw;            // 目标旋转的角速度
        
        float r1;               // 目标其中一组装甲板相对中心的半径
        float r2;               // 目标另一组装甲板相对中心的半径

        float dz; // tracking 中的装甲板的上一块装甲板的 z 轴位置
    } __packed__ data;
    uint16_t crc;
} __packed__ ReceiveDataVision_s;

// 导航控制数据包
typedef struct
{
    FrameHeader_t frame_header;  // 数据段id = 0x03
    uint32_t time_stamp;
    // uint8_t header;
    // uint8_t id;                    // 数据段id = 0xA4
    struct
    {
        float linear_x;
        float linear_y;
        float linear_z;
        float angular_x;
        float angular_y;
        float angular_z;
    } __packed__ data;
    uint16_t crc;
} __packed__ ReceiveDataSimulation_s;

#endif  // USB_TYPEDEF_H
